package gui;

import entities.Album;
import entities.MusicGroup;
import entities.MusicProductionCompany;
import entities.Song;
import helpers.ValidationHelper;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


// Διάλογος Διαχείρισης Άλμπουμ Συγκροτήματος
public class MusicGroupAlbumForm extends javax.swing.JDialog {
    private String dialogResult = "Cancel";
    private final ValidationHelper validator = new ValidationHelper();
    
    public MusicGroupAlbumForm(Album _entity) {
        initComponents();
        
        // Εμφάνισε το παράθυρο σαν modal και σε κέντρο σε σχέση με την parent form
        this.setModal(true);
        this.setLocationRelativeTo(this.getOwner());
        
        entity = _entity;
        
        updateControlsFromEntity();
    }
    
    // Constructor χωρίς ορίσματα που κάνει κλήση του παραπάνω constructor
    // με όρισμα νέο αντικείμενο
    public MusicGroupAlbumForm() {
        this(new Album());
    }
    
    // Ενημέρωση των των controls από τα properties του entity
    private void updateControlsFromEntity(){
        // Αν το id του entity δεν είναι null, το αντικείμενο είναι persisted
        // οπότε αρχικοποιούμε τις τιμές των controls
        if (entity.getId() != null) {
            this.titleText.setText(entity.getTitle());
            this.diskNumberSpinner.setValue(entity.getDiskNumber());
            this.dateTextField.setText(validator.getDF().format(entity.getReleaseDate()));
            this.albumTypeComboBox.setSelectedItem(entity.getType());
            this.companyComboBox.setSelectedItem(entity.getMusicProductionCompanyId());
            this.musicGroupComboBox.setSelectedItem(entity.getMusicGroupId());        

            this.songList.clear();
            this.songList.addAll(entity.getSongList());
        }
    }
    
    // Ενημέρωση των properties του entity από τις τιμές των controls
    private void updateEntityFromControls() {
        entity.setTitle(titleText.getText());
        entity.setType((String)albumTypeComboBox.getSelectedItem());
        entity.setDiskNumber((int)this.diskNumberSpinner.getValue());
        entity.setMusicGroupId((MusicGroup)this.musicGroupComboBox.getSelectedItem());
        entity.setMusicProductionCompanyId((MusicProductionCompany)this.companyComboBox.getSelectedItem());
        
        if (validator.isValidDate(this.dateTextField.getText())){
            entity.setReleaseDate(validator.parseDate(this.dateTextField.getText()));
        }
        
        entity.setSongList(songList);
    }
    
    // Επιστρέφει το entity της φόρμας
    public Album getEntity()
    {
        updateEntityFromControls();
        return entity;
    }
    
    // Επιστρέφει την τρέχουσα τιμή του dialogResult (Save/Cancel)
    public String getDialogResult()
    {
        return this.dialogResult;
    }
    
    //Ελέγχει αν υπάρχει στην λίστα δύο φορές τραγούδι με τον ίδιο τίτλο
    //Επιστρέφει true αν βρεί διπλότυπο τραγούδι
    public boolean checkForDuplicateSong()
    {
        List<String> names = new ArrayList<>();
        for (Song s : songList){
            names.add(s.getTitle());
        }
        Set<String> set = new HashSet<>(names);
        return set.size() < names.size(); // true = έχει διπλότυπα
    }
    
    // Κλείνει το διάλογο αφού πρώτα κάνει τους απαραίτητους ελέγχους
    protected void closeDialog(String _dialogResult) {
        if (_dialogResult != null && !_dialogResult.isEmpty()){
            dialogResult = _dialogResult;
        }
        if ((this.dialogResult.equals("Save") && validateEntity()) || this.dialogResult.equals("Cancel")){
            this.dispose();
        }
    }
    
    // Έλεγχος εγκυρότητας δεδομένων πριν την αποθήκευση
    // με χρήση ενός managers.ValidationHelper
    protected boolean validateEntity(){
        validator.getRules().clear();
        validator.addRule(songList.size() < 1, "Το Άλμπουμ Συγκροτήματος πρέπει να περιέχει τουλάχιστον ένα τραγούδι !");
        validator.addRule(this.checkForDuplicateSong(), "Το Άλμπουμ Συγκροτήματος δεν πρέπει να περιέχει τραγούδια με τον ίδιο τίτλο !");
        validator.addDateRule(this.dateTextField.getText());
        
        return validator.validateRules(this);
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        em = java.beans.Beans.isDesignTime() ? null : javax.persistence.Persistence.createEntityManagerFactory("KLMRadioStationPU").createEntityManager();
        entity = new entities.Album();
        musicProductionCompanyQuery = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT m FROM MusicProductionCompany m");
        musicProductionCompanyList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : musicProductionCompanyQuery.getResultList();
        musicGroupQuery = java.beans.Beans.isDesignTime() ? null : em.createQuery("SELECT m FROM MusicGroup m");
        musicGroupList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : musicGroupQuery.getResultList();
        songQuery = java.beans.Beans.isDesignTime() ? null : em.createQuery("Select s FROM Song s where s.albumId.id = -1");
        songList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : org.jdesktop.observablecollections.ObservableCollections.observableList(new java.util.LinkedList(songQuery.getResultList()));
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        titleText = new javax.swing.JTextField();
        companyComboBox = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        albumTypeComboBox = new javax.swing.JComboBox();
        diskNumberSpinner = new javax.swing.JSpinner();
        musicGroupComboBox = new javax.swing.JComboBox();
        dateTextField = new javax.swing.JFormattedTextField();
        insertSongButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        removeSongButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Διαχείριση Καλλιτέχνη");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        saveButton.setText("Αποθήκευση");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Άκυρο");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("Αριθμός Άλμπουμ");

        org.jdesktop.swingbinding.JComboBoxBinding jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, musicProductionCompanyList, companyComboBox);
        bindingGroup.addBinding(jComboBoxBinding);

        jLabel2.setText("Τίτλος");

        jLabel3.setText("Τύπος Άλμπουμ");

        jLabel4.setText("Εταιρεία Παραγωγής");

        jLabel5.setText("Συγκρότημα");

        jLabel6.setText("Ημερομηνία Κυκλοφορίας");

        jLabel7.setText("Λίστα Τραγουδιών");

        albumTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "CS", "EP", "LP" }));

        jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, musicGroupList, musicGroupComboBox);
        bindingGroup.addBinding(jComboBoxBinding);

        dateTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.DateFormatter(new java.text.SimpleDateFormat("dd/MM/yyyy"))));

        insertSongButton.setText("Εισαγωγή Τραγουδιού");
        insertSongButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                insertSongButtonActionPerformed(evt);
            }
        });

        table.setCellSelectionEnabled(true);
        table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);

        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, songList, table);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${trackNr}"));
        columnBinding.setColumnName("Αρ. Κομματιού");
        columnBinding.setColumnClass(Integer.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${title}"));
        columnBinding.setColumnName("Τίτλος");
        columnBinding.setColumnClass(String.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${duration}"));
        columnBinding.setColumnName("Διάρκεια");
        columnBinding.setColumnClass(Integer.class);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();
        jScrollPane2.setViewportView(table);
        table.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);

        removeSongButton.setText("Διαγραφή Τραγουδιού");
        removeSongButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeSongButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(saveButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4)
                            .addComponent(jLabel5)
                            .addComponent(jLabel6)
                            .addComponent(jLabel7))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(musicGroupComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(companyComboBox, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(diskNumberSpinner, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(albumTypeComboBox, javax.swing.GroupLayout.Alignment.TRAILING, 0, 195, Short.MAX_VALUE)
                            .addComponent(titleText, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(dateTextField)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(insertSongButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(removeSongButton))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(titleText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(albumTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(diskNumberSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(companyComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(musicGroupComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel6)
                    .addComponent(dateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(12, 12, 12)
                .addComponent(jLabel7)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(insertSongButton)
                    .addComponent(removeSongButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 211, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton)
                    .addComponent(cancelButton))
                .addContainerGap())
        );

        getAccessibleContext().setAccessibleName("Διαχείριση Άλμπουμ Συγκροτήματος");
        getAccessibleContext().setAccessibleDescription("");

        bindingGroup.bind();

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        closeDialog("Save");
    }//GEN-LAST:event_saveButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        closeDialog("Cancel");
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void insertSongButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_insertSongButtonActionPerformed
        Song s = new Song();
        s.setAlbumId(entity);  
        songList.add(s);
    }//GEN-LAST:event_insertSongButtonActionPerformed

    private void removeSongButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeSongButtonActionPerformed
        Song song = songList.get(table.convertRowIndexToModel(table.getSelectedRow()));
        songList.remove(song);
    }//GEN-LAST:event_removeSongButtonActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        closeDialog("Cancel");
    }//GEN-LAST:event_formWindowClosing

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox albumTypeComboBox;
    private javax.swing.JButton cancelButton;
    private javax.swing.JComboBox companyComboBox;
    private javax.swing.JFormattedTextField dateTextField;
    private javax.swing.JSpinner diskNumberSpinner;
    private javax.persistence.EntityManager em;
    private entities.Album entity;
    private javax.swing.JButton insertSongButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JComboBox musicGroupComboBox;
    private java.util.List<entities.MusicGroup> musicGroupList;
    private javax.persistence.Query musicGroupQuery;
    private java.util.List<entities.MusicProductionCompany> musicProductionCompanyList;
    private javax.persistence.Query musicProductionCompanyQuery;
    private javax.swing.JButton removeSongButton;
    private javax.swing.JButton saveButton;
    private java.util.List<entities.Song> songList;
    private javax.persistence.Query songQuery;
    private javax.swing.JTable table;
    private javax.swing.JTextField titleText;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
